/**
 * com.helios.boot.config.HeliosHttpMessageConvertConfig.java
 * Copyright (c) 2018-2019 上海纬视瑞信息科技有限公司
 * Shanghai Visionary Information Technology Inc., Ltd
 * Create : 2019年6月29日
 */
package com.qing.administer.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.BigIntegerCodec;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.NameFilter;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;

import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

/**
 * @author huang.zhong
 * @since 2019年6月29日
 * @version 1.0.0
 */
@Configuration
public class HttpMessageConvertConfig {
	/**
	 * fastJson 消息转换
	 * 
	 * @return
	 * @author huang.zhong
	 * @since 2019年6月26日
	 * @version 1.0.0
	 */
	@Bean
	public HttpMessageConverters fastJsonHttpMessageConverters() {
		FastJsonHttpMessageConverter fasHttpMessageConverter = new FastJsonHttpMessageConverter();
		FastJsonConfig fastJsonConfig = new FastJsonConfig();
		fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat
				, SerializerFeature.SortField
				, SerializerFeature.MapSortField
				, SerializerFeature.QuoteFieldNames
				, SerializerFeature.WriteMapNullValue
				, SerializerFeature.WriteNullListAsEmpty
				, SerializerFeature.WriteNullBooleanAsFalse
				, SerializerFeature.WriteDateUseDateFormat);
		// 序列化配置
		SerializeConfig serializeConfig = new SerializeConfig();
		NameFilter nameFilter = (object, name, value) -> name;
        //解决JS中精度丢失问题
        serializeConfig.put(Long.class, LongCodec.instance);
        serializeConfig.put(Long.TYPE, LongCodec.instance);
        serializeConfig.put(BigInteger.class, BigIntegerCodec.instance);
        fastJsonConfig.setDateFormat(JSON.DEFFAULT_DATE_FORMAT);
        fastJsonConfig.setSerializeConfig(serializeConfig);
        
		// 在converter中添加配置信息
		fasHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
		// 中文乱码解决方案
		List<MediaType> mediaTypes = new ArrayList<>();
		mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
		mediaTypes.add(MediaType.APPLICATION_JSON);
		mediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
		mediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
		mediaTypes.add(MediaType.TEXT_HTML);
		mediaTypes.add(MediaType.MULTIPART_FORM_DATA);
		mediaTypes.add(MediaType.IMAGE_GIF);
		mediaTypes.add(MediaType.IMAGE_JPEG);
		mediaTypes.add(MediaType.IMAGE_PNG);
		mediaTypes.add(new MediaType("application", "vnd.spring-boot.actuator.v2+json"));
		fasHttpMessageConverter.setSupportedMediaTypes(mediaTypes);

		HttpMessageConverter<?> converter = fasHttpMessageConverter;
		return new HttpMessageConverters(converter);
	}

	static class LongCodec extends com.alibaba.fastjson.serializer.LongCodec {

		public static final LongCodec instance = new LongCodec();

		@Override
		public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
						  int features) throws IOException {
			SerializeWriter out = serializer.out;

			if (object == null) {
				out.writeNull();
				return;
			}

			String strVal = object.toString();

			if (strVal.length() > 16) {
				out.writeString(strVal);
			} else {
				out.writeLong(((Long) object).longValue());
			}
		}

	}
}
